<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Object-oriented programming II in Visual Basic</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Visual Basic, learn Visual Basic, OOP, object-oriented programming, programming, language">
<meta name="description" content="This part of the Visual Basic tutorial we continue 
describing object-oriented programming in Visual Basic.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">

<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Object-oriented programming II</h1>

<p>
In this chapter of the Visual Basic tutorial, we continue description of the OOP 
in the Visual Basic language. 
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div>

<h2>Interfaces</h2>

<p>
A remote control is an interface between the viewer and the TV. It is an interface to this electronic
device. Diplomatic protocol guides all activities in the diplomatic field. Rules of the road are rules
that motorists, cyclists and pedestrians must follow. Interfaces in programming are
analogous to the previous examples. 
</p>

<p>
Interfaces are:
</p>

<ul>
<li>APIs</li>
<li>Contracts</li>
</ul>

<p>
Objects interact with the outside world with the methods, they expose. The actual implementation is not
important to the programmer, or it also might be secret. A company might sell a library and it does not
want to disclose the actual implementation. A programmer might call a Maximize method on a window
of a GUI toolkit, but knows nothing about how this method is implemented. From this point of view, 
interfaces are methods, through which objects interact with the outside world, without exposing too much
about their inner workings.
</p>

<p>
From the second point of view, interfaces are contracts. If agreed upon, they must be followed. They 
are used to design an architecture of an application. They help organize the code.  
</p>

<p>
Interfaces are fully abstract types. They are declared using the <code>Interface</code> keyword. 
Interfaces can only have method signatures and constants. All method signatures declared in an interface must be public.
They cannot have fully implemented methods, nor 
member fields. A Visual Basic class may implement any number of interfaces. An interface can also extend
any number of interfaces. A class that implements an interface must implement all method signatures of
an interface.  
</p>

<p>
Interfaces are used to simulate <b>multiple inheritance</b>. A Visual Basic class can inherit only from one class. 
A Visual Basic class can implement multiple interfaces. Multiple inheritance using the interfaces is not 
about inheriting methods and variables. It is about inheriting ideas or contracts, which are described
by the interfaces. 
</p>

<p>
There is one important distinction between interfaces and abstract classes. Abstract classes provide partial
implementation for classes, that are related in the inheritance hierarchy. Interfaces on the other hand can 
be implemented by classes, that are not related to each other. For example, we have two buttons.
A classic button and a round button. Both inherit from an abstract button class, that provides some
common functionality to all buttons. Implementing classes are related, since all are buttons. 
Another example might have classes Database and SignIn. They are not related to each other. We
can apply an ILoggable interface, that would force them to create a method to do logging. 
</p>

<pre class="code">
Option Strict On


Module Example

    Interface IInfo

       Sub DoInform()
    
    End Interface

    Class Some
        Implements IInfo

        Sub DoInform() Implements IInfo.DoInform
            Console.WriteLine("This is Some Class")
        End Sub
    
    End Class

    Sub Main()
        
        Dim sm As New Some
        sm.DoInform()    

    End Sub
    
End Module
</pre>

<p>
This is a simple Visual Basic program demonstrating an interface.
</p>

<pre class="explanation">
Interface IInfo
    Sub DoInform()
End Interface
</pre>

<p>
This is an interface <code>IInfo</code>. It has the DoInform()
method signature.
</p>

<pre class="explanation">
Class Some
    Implements IInfo
</pre>

<p>
We use the <code>Implements</code> to implement from an
interface. 
</p>

<pre class="explanation">
Sub DoInform() Implements IInfo.DoInform
    Console.WriteLine("This is Some Class")
End Sub
</pre>

<p>
The class provides an implementation for the DoInform() method. 
The <code>Implements</code> keyword explicitly specifies 
which method signature we are implementing. 
</p>

<hr class="btm">

<p>
The next example shows, how a class can implement multiple
interfaces.
</p>

<pre class="code">
Option Strict On


Module Example

    Interface Device

       Sub SwitchOn()
       Sub SwitchOff()
    
    End Interface

    Interface Volume

       Sub VolumeUp()
       Sub VolumeDown()
    
    End Interface

    Interface Pluggable

       Sub PlugIn()
       Sub PlugOff()
    
    End Interface

    Class CellPhone
        Implements Device, Volume, Pluggable

        Public Sub SwitchOn() Implements Device.SwitchOn
            Console.WriteLine("Switching on")
        End Sub

        Public Sub SwitchOff() Implements Device.SwitchOff
            Console.WriteLine("Switching on")
        End Sub

        Public Sub VolumeUp() Implements Volume.VolumeUp
            Console.WriteLine("Volume up")
        End Sub

        Public Sub VolumeDown() Implements Volume.VolumeDown
            Console.WriteLine("Volume down")
        End Sub

        Public Sub PlugIn() Implements Pluggable.PlugIn
            Console.WriteLine("Plugging In")
        End Sub

        Public Sub PlugOff() Implements Pluggable.PlugOff
            Console.WriteLine("Plugging Off")
        End Sub
    
    End Class

    Sub Main()
        
        Dim o As New CellPhone
        o.SwitchOn()
        o.VolumeUp()
        o.PlugIn()

    End Sub
    
End Module
</pre>

<p>
We have a <b>CellPhone</b> class that inherits from three interfaces. 
</p>

<pre class="explanation">
Class CellPhone
    Implements Device, Volume, Pluggable
</pre>

<p>
The class implements all three interfaces, which are divided by a comma.
The CellPhone class must implement all method signatures from all three interfaces. 
</p>

<pre>
$ ./interface.exe 
Switching on
Volume up
Plugging In
</pre>

<p>
Running the program. 
</p>

<hr class="btm">

<p>
The next example shows how interfaces can inherit from multiple other
interfaces. 
</p>

<pre class="code">
Option Strict On


Module Example

    Interface IInfo

        Sub DoInform()
    
    End Interface

    Interface IVersion

       Sub GetVersion()
    
    End Interface

    Interface ILog
        Inherits IInfo, IVersion

       Sub DoLog
    
    End Interface

    Class DBConnect
        Implements ILog

        Public Sub DoInform() Implements IInfo.DoInform
            Console.WriteLine("This is DBConnect class")
        End Sub

        Public Sub GetVersion() Implements IVersion.GetVersion
            Console.WriteLine("Version 1.02")
        End Sub

        Public Sub DoLog() Implements ILog.DoLog
            Console.WriteLine("Logging")
        End Sub

        Public Sub Connect()
            Console.WriteLine("Connecting to the database")
        End Sub
    
    End Class

    Sub Main()
        
        Dim db As New DBConnect
        db.DoInform()
        db.GetVersion()
        db.DoLog()
        db.Connect()

    End Sub
    
End Module
</pre>

<p>
We define three interfaces. We can organize interfaces in hierarchy.
</p>

<pre class="explanation">
Interface ILog
    Inherits IInfo, IVersion
</pre>

<p>
The <b>ILog</b> interface inherits from two other interfaces.
</p>

<pre class="explanation">
Public Sub DoInform() Implements IInfo.DoInform
    Console.WriteLine("This is DBConnect class")
End Sub
</pre>

<p>
The DBConnect class implements the DoInform() method. 
This method was inherited by the ILog interface, 
which the class implements. 
</p>

<pre>
$ ./interface2.exe 
This is DBConnect class
Version 1.02
Logging
Connecting to the database
</pre>

<p>
Output.
</p>

<h2>Polymorphism</h2>

<p>
The polymorphism is the process of using an operator or function in different ways for different data input.
In practical terms, polymorphism means that if class B inherits from class A, it doesn't have to
inherit everything about class A; it can do some of the things that class A does differently. (wikipedia)
</p>

<p>
In general, polymorphism is the ability to appear in different forms. Technically, it is the ability 
to redefine methods for derived classes. Polymorphism is concerned with the application of specific implementations
to an interface or a more generic base class. 
</p>

<p>
Polymorphism is the ability to redefine methods for derived classes.
</p>

<pre class="code">
Option Strict On


Module Example

    MustInherit Class Shape

        Protected x As Integer
        Protected y As Integer
    
        Public MustOverride Function Area() As Integer

    End Class

    Class Rectangle 
        Inherits Shape
    
        Sub New(ByVal x As Integer, ByVal y As Integer)
            Me.x = x
            Me.y = y
        End Sub

        Public Overrides Function Area() As Integer
            Return Me.x * Me.y
        End Function
 
    End Class


    Class Square 
        Inherits Shape
    
        Sub New(ByVal x As Integer)
            Me.x = x
        End Sub

        Public Overrides Function Area() As Integer
            Return Me.x * Me.x
        End Function

    End Class

    Sub Main()
        
        Dim shapes() As Shape = { New Square(5), _
            New Rectangle(9, 4), New Square(12) } 

        For Each shape As Shape In shapes
            Console.WriteLine(shape.Area())
        Next

    End Sub
    
End Module
</pre>

<p>
In the above program, we have an abstract Shape class. This class morphs into two 
descendant classes, Rectangle and Square. Both provide their own implementation of
the Area() method. Polymorphism brings flexibility and scalability to the OOP systems. 
</p>

<pre class="explanation">
Public Overrides Function Area() As Integer
    Return Me.x * Me.y
End Function
...
Public Overrides Function Area() As Integer
    Return Me.x * Me.x
End Function
</pre>

<p>
Rectangle and Square classes have their own implementations of the
Area method.
</p>

<pre class="explanation">
Dim shapes() As Shape = { New Square(5), _
    New Rectangle(9, 4), New Square(12) } 
</pre>

<p>
We create an array of three Shapes. 
</p>

<pre class="explanation">
For Each shape As Shape In shapes
    Console.WriteLine(shape.Area())
Next
</pre>

<p>
We go through each shape and call Area method on it. 
The compiler calls the correct method for each shape. This
is the essence of polymorphism.
</p>


<h2>NotOverridable, NotInheritable</h2>

<p>
<code>NotOverridable</code> methods cannot be overridden and 
<code>NotInheritable</code> classes cannot be inherited from. 
These keywords are a matter of a design of the application.
We should not inherit from some classes and some methods should not be overridden. 
</p>


<pre class="code">
Option Strict On


Module Example

    Class Base

        Public NotOverridable Sub Say()
            Console.WriteLine("Base class")
        End Sub

    End Class

    Class Derived
        Inherits Base

        Public Overrides Sub Say()
            Console.WriteLine("Derived class")
        End Sub

    End Class

    Sub Main()

        Dim o As Base = New Derived
        o.Say()

    End Sub

End Module
</pre>

<p>
This program won't compile. We get an error 'Public Overrides Sub Say()' 
cannot override 'Public NotOverridable Sub Say()' because it is declared 'NotOverridable'.        
</p>


<pre class="code">
Option Strict On


Module Example

    NotInheritable Class Math

        Public Shared Function getPI() As Single
            Return 3.141592
        End Function

    End Class

    Class DerivedMath
        Inherits Math

        Public Sub Say()
            Console.WriteLine("DerivedMath class")
        End Sub

    End Class

    Sub Main()

        Dim o As DerivedMath = New DerivedMath
        o.Say()

    End Sub

End Module
</pre>

<p>
In the above program, we have a prototype base Math class. The sole purpose of this 
class is to provide some helpful methods and constants to the programmer. (In our case we have
only one method for simplicity reasons.) It is not created to be inherited from. To prevent uninformed
other programmers to derive from this class, the creators made the class <code>NotInheritable</code>. 
If you try to compile this program, you get the following error: 'DerivedMath' cannot inherit from class
'Math' because 'Math' is declared 'NotInheritable'.     
</p>

<h2>Deep copy vs shallow copy</h2>

<p>
Copying of data is an important task in programming. Object is a composite data type in OOP. 
Member field in an object may be stored by value or by reference. Copying may be performed in
two ways. 
</p>

<p>
The <b>shallow copy</b> copies all values and references into a new instance. The data to which a
reference is pointing is not copied; only the pointer is copied. The new references
are pointing to the original objects. Any changes to the reference members affect both objects. 
</p>

<p>
The <b>deep copy</b> copies all values into a new instance. In case of members that are stored as
references a deep copy performs a deep copy of data, that is being referenced. A new copy of a referenced
object is created. And the pointer to the newly created object is stored. Any changes to those referenced
objects will not affect other copies of the object. Deep copies are fully replicated objects. 
</p>

<p>
If a member field is a value type, a bit-by-bit copy of the field is performed. 
If the field is a reference type, the reference is copied but the referred object is not; 
therefore, the reference in the original object and the reference 
in the clone point to the same object. (a clear explanation from programmingcorner.blogspot.com)
</p>

<p>
The next two examples will perform a shallow and a deep copy on objects. 
</p>

<pre class="code">
Option Strict On


Module Example

    Class Color

        Public red as Byte
        Public green as Byte
        Public blue as Byte
 
        Sub New(red As Byte, green As Byte, _
            blue As Byte)
            Me.red = red
            Me.green = green
            Me.blue = blue
        End Sub

    End Class

    Class MyObject
        Implements ICloneable

        Public Id As Integer
        Public Size As String
        Public Col As Color

        Sub New(Id As Integer, Size As String, _
            Col As Color)
            Me.Id = Id
            Me.Size = Size
            Me.Col = Col
        End Sub

        Public Function Clone() As Object _
                          Implements ICloneable.Clone
          Return New MyObject(Me.Id, Me.Size, Me.Col)
        End Function

        Public Overrides Function ToString() As String
            Dim s As String
            s = String.Format("Id: {0}, Size: {1}, Color:({2}, {3}, {4})", _
                Me.Id, Me.Size, Me.Col.red, Me.Col.green, Me.Col.blue)
            Return s
        End Function

    End Class

    Sub Main()
        
        Dim col As New Color(23, 42, 223)    
        
        Dim obj1 As New MyObject(23, "small", col)
        Dim obj2 As MyObject

        obj2 = CType(obj1.Clone(), MyObject)
        
        obj2.Id += 1
        obj2.Size = "big"         
        obj2.Col.red = 255
         
        Console.WriteLine(obj1) 
        Console.WriteLine(obj2)

    End Sub
    
End Module
</pre>

<p>
This is an example of a shallow copy. 
We define two custom objects. MyObject and Color. The MyObject object
will have a reference to the Color object. 
</p>

<pre class="explanation">
Class MyObject
    Implements ICloneable
</pre>

<p>
We should implement <code>ICloneable</code> interface for 
objects, which we are going to clone. 
</p>

<pre class="explanation">
Public Function Clone() As Object _
                  Implements ICloneable.Clone
    Return New MyObject(Me.Id, Me.Size, Me.Col)
End Function
</pre>

<p>
The <code>ICloneable</code> interface forces us
to create a <code>Clone()</code> method. This
method returns a new object with copied values.
</p>

<pre class="explanation">
Dim col As New Color(23, 42, 223)  
</pre>

<p>
We create an instance of the Color object. 
</p>

<pre class="explanation">
Dim obj1 As New MyObject(23, "small", col)
</pre>

<p>
An instance of the MyObject object is created. It passes the
instance of the Color object to its constructor. 
</p>

<pre class="explanation">
obj2 = CType(obj1.Clone(), MyObject)
</pre>

<p>
We create a shallow copy of the obj1 object and assign it
to the obj2 variable. The Clone() method returns an Object
and we expect MyObject. This is why we do explicit casting. 
</p>


<pre class="explanation">
obj2.Id += 1
obj2.Size = "big"         
obj2.Col.red = 255
</pre>

<p>
Here we modify the member fields of the copied object. 
We increment the Id, change the Size to "big" and change 
the red part of the color object.
</p>

<pre class="explanation">
Console.WriteLine(obj1) 
Console.WriteLine(obj2)
</pre>

<p>
The <code>Console.WriteLine()</code> method calls the
<code>ToString()</code> method of the obj2 object, which
returns the string representation of the object. 
</p>

<pre>
Id: 23, Size: small, Color:(255, 42, 223)
Id: 24, Size: big, Color:(255, 42, 223)
</pre>

<p>
We can see, that the Ids are different. 23 vs 24. The Size is different.
"small" vs "big". But the red part of the color object is same for both instances.
255. Changing member values of the cloned object (Id, Size) did not affect the original object.
Changing members of the referenced object (Col) has affected the original object too. 
In other words, both objects refer to the same color object in memory.
</p>

<p>
To change this behaviour, we will do a deep copy next. 
</p>

<pre class="code">
Option Strict On


Module Example

    Class Color
        Implements ICloneable

        Public Red as Byte
        Public Green as Byte
        Public Blue as Byte
 
        Sub New(Red As Byte, Green As Byte, _
            Blue As Byte)
            Me.Red = Red
            Me.Green = Green
            Me.Blue = Blue
        End Sub

        Public Function Clone() As Object _
                          Implements ICloneable.Clone
          Return New Color(Me.Red, Me.Green, Me.Blue)
        End Function

    End Class

    Class MyObject
        Implements ICloneable

        Public Id As Integer
        Public Size As String
        Public Col As Color

        Sub New(Id As Integer, Size As String, _
            Col As Color)
            Me.Id = Id
            Me.Size = Size
            Me.Col = Col
        End Sub

        Public Function Clone() As Object _
                          Implements ICloneable.Clone
            Return New MyObject(Me.Id, Me.Size, CType(Me.Col.Clone(), Color))
        End Function

        Public Overrides Function ToString() As String
            Dim s As String
            s = String.Format("Id: {0}, Size: {1}, Color:({2}, {3}, {4})", _
                Me.Id, Me.Size, Me.Col.Red, Me.Col.Green, Me.Col.Blue)
            Return s
        End Function

    End Class

    Sub Main()
        
        Dim col As New Color(23, 42, 223)    
        
        Dim obj1 As New MyObject(23, "small", col)
        Dim obj2 As MyObject

        obj2 = CType(obj1.Clone(), MyObject)
        
        obj2.Id += 1
        obj2.Size = "big"         
        obj2.Col.Red = 255
         
        Console.WriteLine(obj1) 
        Console.WriteLine(obj2)


    End Sub
    
End Module
</pre>

<p>
In this program, we perform a deep copy on object.
</p>

<pre class="explanation">
Class Color
    Implements ICloneable
</pre>

<p>
Now the Color class implements the <code>ICloneable</code>
interface.
</p>

<pre class="explanation">
Public Function Clone() As Object _
                  Implements ICloneable.Clone
    Return New Color(Me.Red, Me.Green, Me.Blue)
End Function
</pre>

<p>
We have a <code>Clone()</code> method for the Color class
too. This helps to create a copy of a referenced object.
</p>


<pre class="explanation">
Public Function Clone() As Object _
                  Implements ICloneable.Clone
    Return New MyObject(Me.Id, Me.Size, CType(Me.Col.Clone(), Color))
End Function
</pre>

<p>
Now, when we clone the MyObject, we call the <code>Clone()</code>
method upon the Col reference type. This way we have a copy of 
a color value too.
</p>


<pre>
$ ./deepcopy.exe 
Id: 23, Size: small, Color:(23, 42, 223)
Id: 24, Size: big, Color:(255, 42, 223)
</pre>

<p>
Now the red part of the referenced Color object is not the same. The original object 
has retained its previous 23 value.
</p>

<h2>Exceptions</h2>

<p>
Exceptions are designed to handle the occurrence of exceptions, special conditions that
change the normal flow of program execution. Exceptions are raised or thrown, initiated. 
</p>

<p>
During the execution of our application,
many things might go wrong. A disk might get full and we cannot save our file.
An Internet connection might go down and our application tries to connect to a site.
All these might result in a crash of our application. To prevent happening this,
we must cope with all possible errors that might occur. For this, we can use the exception handling.
</p>

<p>
The <code>Try</code>, <code>Catch</code> and <code>Finally</code> 
keywords are used to work with exceptions. 
</p>

<pre class="code">
Option Strict On

Module Example

    Sub Main()
    
        Dim x As Integer = 100
        Dim y As Integer = 0    
        Dim z As Double
        
        Try 
            z = x \ y
        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try

    End Sub

End Module
</pre>

<p>
In the above program, we intentionally divide a number by zero. This leads to an error.
</p>

<pre class="explanation">
Try 
    z = x \ y
...
End Try
</pre>

<p>
Statements that are error prone are placed after the <code>Try</code>
keyword.
</p>


<pre class="explanation">
Catch e As Exception
    Console.WriteLine(e.Message)
...
</pre>

<p>
Exception types follow the <code>Catch</code>
keyword. In our case we have a generic <code>Exception</code> which will
catch an exception of any type. There are some generic exceptions and some more specific. 
Statements that follow the Catch keyword are executed, when an error occurs.
When an exception occurs, an exception object is created. From this object we
get the Message property and print it to the console. 
</p>

<hr class="btm">

<p>
Any uncaught exception in the current context propagates to a higher context and looks 
for an appropriate catch block to handle it. If it can't find any suitable catch 
blocks, the default mechanism of the .NET runtime will terminate the execution 
of the entire program.
</p>

<pre class="code">
Option Strict On

Module Example

    Sub Main()
 
        Dim z As Double
        Dim x As Integer = 100
        Dim y As Integer = 0
        
        z = x \ y

    End Sub

End Module
</pre>

<p>
In this program, we divide by zero. We have no custom
exception handling. On Visual Basic 2008 Express we
receive the following error message:
'Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.'.
</p>

<hr class="btm">


<pre class="code">
Option Strict On

Imports System.IO

Module Example

    Dim fs As FileStream

    Sub Main()

        Try
            fs = File.Open("file", FileMode.OpenOrCreate)
            Console.WriteLine(fs.Length)
        Catch e As IOException
            Console.WriteLine("IO Error")
            Console.WriteLine(e.Message)
        Finally
            Console.WriteLine("Finally")
            If fs.CanRead = True Then
                fs.Close()
            End If
        End Try

    End Sub

End Module
</pre>

<p>
The statements following the <code>Finally</code> keyword are always executed.
It is often used to clean-up tasks, such as closing files or clearing buffers.
</p>

<pre class="explanation">
Catch e As IOException
    Console.WriteLine("IO Error")
    Console.WriteLine(e.Message)
</pre>

<p>
In this case, we catch for a specific <code>IOException</code> exception.
</p>

<pre class="explanation">
Finally
    Console.WriteLine("Finally")
    If fs.CanRead = True Then
        fs.Close()
    End If
</pre>

<p>
These lines guarantee that the file handler is closed.
</p>

<hr class="btm">

<pre class="code">
Option Strict On

Module Example

    Sub Main()

        Dim x As Integer
        Dim y As Integer
        Dim z As Double

        Try
            Console.Write("Enter first number: ")
            x = Convert.ToInt32(Console.ReadLine())

            Console.Write("Enter second number: ")
            y = Convert.ToInt32(Console.ReadLine())

            z = x / y
            Console.WriteLine("Result: {0:D} / {1:D} = {2:D}", x, y, z)

        Catch e As DivideByZeroException
            Console.WriteLine("Cannot divide by zero.")
        Catch e As FormatException
            Console.WriteLine("Wrong format of number.")
        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try

    End Sub

End Module
</pre>

<p>
In this example, we catch for various exceptions. Note that more specific exceptions should
precede the generic ones. We read two numbers from the console and check
for zero division error and for wrong format of number. 
</p>

<pre>
$ ./passing.exe 
Enter first number: et
Wrong format of number.
</pre>

<p>
Running the example. 
</p>

<hr class="btm">

<pre class="code">
Option Strict On

Module Example

    Class BigValueException
        Inherits Exception
    
        Sub New(ByVal msg As String)
            MyBase.New(msg)
        End Sub

    End Class

    Sub Main()
    
        Dim x As Integer = 340004
        Const LIMIT As Integer = 333    
        
        Try 
            If (x > LIMIT) Then
                Throw New BigValueException("Exceeded the maximum value")
            End If
        Catch e As BigValueException
            Console.WriteLine(e.Message)
        End Try

    End Sub

End Module
</pre>

<p>
Let's say, we have a situation in which we cannot deal with big numbers. 
</p>

<pre class="explanation">
Class BigValueException
    Inherits Exception
</pre>

<p>
We have a <b>BigValueException</b> class. This class derives from the 
built-in <code>Exception</code> class.
</p>

<pre class="explanation">
Dim Const LIMIT As Integer = 333 
</pre>

<p>
Numbers bigger than this constant are considered to be "big" by 
our program.
</p>


<pre class="explanation">
Sub New(ByVal msg As String)
    MyBase.New(msg)
End Sub
</pre>

<p>
Inside the constructor, we call the parent's constructor. 
We pass the message to the parent. 
</p>

<pre class="explanation">
If (x > LIMIT) Then
    Throw New BigValueException("Exceeded the maximum value")
End If
</pre>

<p>
If the value is bigger than the limit, we throw our custom exception.
We give the exception a message "Exceeded the maximum value". 
</p>

<pre class="explanation">
Catch e As BigValueException
    Console.WriteLine(e.Message)
</pre>

<p>
We catch the exception and print its message to the console. 
</p>

<h2>Properties</h2>

<p>
Properties are special kind of class members. We use predefined set and
get methods to access and modify them. Property reads and writes
are translated to get and set method calls. Accessing variables with 
a field notation (e.g. object.Name) is easier than with custom method
calls.(e.g. object.GetName()). However with properties, we still have
the advantage of encapsulation and information hiding. 
</p>


<pre class="code">
Option Strict On


Module Example

    Class Person

        Private _name As String

        Public Property Name() As String
            Get
                Return _name
            End Get
         
            Set (Byval Value As String)
                _name = Value
            End Set
        End Property
          
    End Class

    Sub Main()
        
        Dim p as New Person
        p.Name = "Jane"

        Console.WriteLine(p.Name())
  
    End Sub
    
End Module
</pre>

<p>
We have a simple Person class with one property.
</p>

<pre class="explanation">
Public Property Name() As String
...
End Property
</pre>

<p>
We use the <code>Property</code> keyword to
create properties in Visual Basic.
</p>

<pre class="explanation">
Get
    Return _name
End Get
</pre>

<p>
We use the predefined <code>Get</code> keyword to 
create an accessor method to the _name field.
</p>

<pre class="explanation">
Set (Byval Value As String)
    _name = Value
End Set
</pre>

<p>
Similarly, the <code>Set</code> keyword creates
a mutator method for the _name field. 
</p>

<pre class="explanation">
Dim p as New Person
p.Name = "Jane"

Console.WriteLine(p.Name())
</pre>

<p>
We create an instance of the Person class. We access
the member field using the field notation.
</p>

<pre>
$ ./properties.exe 
Jane
</pre>

<p>
This is the outcome of the program. 
</p>


<h2>Delegates</h2>

<p>
A delegate is a form of type-safe function pointer used by the .NET Framework. 
Delegates are often used to implement callbacks and event listeners. 
</p>


<pre class="code">
Option Strict On


Module Example

    Public Delegate Sub NameDelegate(ByVal msg As String)

    Class Person

        Private FirstName As String
        Private SecondName As String

        Sub New(First As String, Second As String)
            Me.FirstName = First
            Me.SecondName = Second
        End Sub

        Public Sub ShowFirstName(msg As String)
            Console.WriteLine(msg &amp; Me.FirstName)
        End Sub

        Public Sub ShowSecondName(msg As String)
            Console.WriteLine(msg &amp; Me.SecondName)
        End Sub
    
    End Class

    Sub Main()
        
        Dim nDelegate As NameDelegate

        Dim per As New Person("Fabius", "Maximus")       

        nDelegate = AddressOf per.ShowFirstName
        nDelegate("Call 1: ")

        nDelegate = AddressOf per.ShowSecondName
        nDelegate("Call 2: ")                    

    End Sub
    
End Module
</pre>

<p>
In the example we have one delegate. This delegate is used to point
to two methods of the Person class. The methods are called with
the delegate.
</p>

<pre class="explanation">
Public Delegate Sub NameDelegate(ByVal msg As String)
</pre>

<p>
The delegate is created with a <code>Delegate</code> keyword.
The delegate signature must match the signature of the method being called
with the delegate.
</p>

<pre class="explanation">
Dim nDelegate As NameDelegate
</pre>

<p>
Here we create a variable of our custom delegate type.
</p>

<pre class="explanation">
nDelegate = AddressOf per.ShowFirstName
nDelegate("Call 1: ")
</pre>

<p>
The <code>AddressOf</code> operator is used to get the
reference to the ShowFirstName() method. Now that we point to the method,
we can call it via the delegate. 
</p>

<pre>
$ ./simpledelegate.exe 
Call 1: Fabius
Call 2: Maximus
</pre>

<p>
Both names are printed via the delegate.
</p>



<h2>Events</h2>

<p>
Events are messages triggered by some action. Click on the button or
tick of a clock are such actions. The object that triggers an event
is called a sender and the object that receives the event is called
a receiver. 
</p>


<pre class="code">
Option Strict On


Module Example

    Public Event ValueFive() 

    Dim Random As Integer

    Public Sub Main()

        AddHandler ValueFive, AddressOf OnFiveEvent

        For i As Integer = 0 To 10

            Randomize()
            Random = CInt(Rnd() * 7)

            Console.WriteLine(Random)

            If Random = 5 Then
                RaiseEvent ValueFive() 
            End If
        Next

    End Sub

    Public Sub OnFiveEvent() 
        Console.WriteLine("Five Event occured")
    End Sub

End Module
</pre>

<p>
We have a simple example in which we create and launch an event. 
An random number is generated. If the number equals to 5 a FiveEvent
event is generated. 
</p>

<pre class="explanation">
Public Event ValueFive() 
</pre>

<p>
An event is declared with a <code>Event</code> keyword.
</p>

<pre class="explanation">
AddHandler ValueFive, AddressOf OnFiveEvent
</pre>

<p>
Here we plug the event called ValueFive() to the 
OnFiveEvent() subroutine. In other words, if the ValueFive
event is triggered, the OnFiveEvent() subroutine is executed. 
</p>

<pre class="explanation">
If Random = 5 Then
    RaiseEvent ValueFive() 
End If
</pre>

<p>
When the random number equals to 5, we raise the ValueFive event.
We use the <code>RaiseEvent</code> keyword.
</p>

<pre>
$ ./event.exe 
0
1
5
Five Event occured
2
5
Five Event occured
6
7
6
3
3
1
</pre>

<p>
Outcome of the program might look like this.
</p>

<hr class="btm">

<p>
Next we have a more complex example. 
</p>


<pre class="code">
Option Strict On


Namespace EventSample

    Public Class FiveEventArgs
        Inherits EventArgs

        Public Count As Integer
        Public Time As Date

        Public Sub New(ByVal Count As Integer, ByVal Time As Date)
            Me.Count = Count
            Me.Time = Time
        End Sub

    End Class

    Public Class Five

        Private Count As Integer = 0

        Public Sub OnFiveEvent(ByVal source As Object, _
                               ByVal e As FiveEventArgs)
            Console.WriteLine("Five event {0} occured at {1}", _
                              e.Count, e.Time)
        End Sub

    End Class

    Public Class RandomGenerator

        Public Event ValueFive(ByVal source As Object, _
                               ByVal e As FiveEventArgs)

        Public Sub Generate()

            Dim Count As Integer = 0
            Dim args As FiveEventArgs

            For i As Byte = 0 To 10
                Dim Random As Integer

                Randomize()
                Random = CInt(Rnd * 6)
                Console.WriteLine(Random)

                If Random = 5 Then
                    Count += 1
                    args = New FiveEventArgs(Count, Now)
                    RaiseEvent ValueFive(Me, args)
                End If
            Next
        End Sub

    End Class

    Public Class Example

        Public Shared Sub Main()

            Dim five As New Five
            Dim gen As New RandomGenerator

            AddHandler gen.ValueFive, AddressOf five.OnFiveEvent

            gen.Generate()

        End Sub

    End Class

End Namespace
</pre>

<p>
We have four classes. FiveEventArgs carries some data with the
event object. The Five class encapsulates the event object. RandomGenerator class 
is responsible for random number generation. It is the event sender. Finally
the Example class, which is the main application object and has the Main() method.
</p>

<pre class="explanation">
Public Class FiveEventArgs
    Inherits EventArgs

    Public Count As Integer
    Public Time As Date
...
</pre>

<p>
The FiveEventArgs carries data inside the event object. It inherits from the
<code>EventArgs</code> base class. The Count and Time members are
data that will be initialized and carried with the event. 
</p>

<pre class="explanation">
If Random = 5 Then
    Count += 1
    args = New FiveEventArgs(Count, Now)
    RaiseEvent ValueFive(Me, args)
End If
</pre>

<p>
If the generated random number equals to 5, we instantiate the
FiveEventArgs class with the current Count and Date values.
The Count variable counts the number of times this event was generated.
The Time value holds the time, when the event was generated.
The event is sent with the <code>RaiseEvent</code> keyword
with the sender object and event arguments. 
</p>


<pre class="explanation">
AddHandler gen.ValueFive, AddressOf five.OnFiveEvent
</pre>

<p>
We plug the ValueFive event to its handler.
</p>

<pre>
$ ./event2.exe 
3
6
5
Five event 1 occured at 9/15/2010 5:06:13 PM
3
5
Five event 2 occured at 9/15/2010 5:06:13 PM
6
3
2
5
Five event 3 occured at 9/15/2010 5:06:13 PM
2
5
Five event 4 occured at 9/15/2010 5:06:13 PM
</pre>

<p>
This is the ouput I got on my computer. 
</p>

<p>
In this part of the Visual Basic tutorial, we continued the discussion of the object-oriented programming
in Visual Basic. 
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div>
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified September 15, 2010  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

